/* Text_MiscExtensions.m				 
 *
 * This category makes dealing with the Text object easier. 
 * See the docu for details.
 *
 * For interface-info see the header file. The comments in this file mostly
 * cover only the real implementation details.
 *
 * Written by: 		Thomas Engel
 * Created:    		30.01.1995 (Copyleft)
 * Last modified: 	30.01.1995
 */

// The following define is a fake. Looks like NeXT...but it is a cheatmode
// action.
// We don't have a RTFD paste type. But I really need one !

#define NXRTFDPboardType NXUniqueString("NeXT RTFD pasteboard type")


#import "Text_MiscExtensions.h"
#import <misckit/MiscTextExtensions.h>

@implementation Text(MoreMiscExtensions)

- copyTo:aPasteboard
{
	NXAtom textTypes[5];

	if( [self isMonoFont] )
	{
		textTypes[0] = NXAsciiPboardType;
		textTypes[1] = NULL;
	}
	// In the other case we will cheat. The RTFD type was NEVER defined by
	// NeXT. But we will use it...it works. (see the define)

	else
	{
		textTypes[0] = NXRTFDPboardType;
		textTypes[1] = NXTIFFPboardType;
		textTypes[2] = NXRTFPboardType;
		textTypes[3] = NXAsciiPboardType;
		textTypes[4] = NULL;
	}
	[self writeSelectionToPasteboard:aPasteboard types:textTypes];
	return self;
}

- cutTo:aPasteboard
{
	[self copyTo:aPasteboard];
	[self delete:self];
	return self;
}

- pasteFrom:aPasteboard
{
	NXSelPt	start;
	NXSelPt	end;

	if( [self hasInvalidSelection] )
		[self setSelToEnd];
	[self readSelectionFromPasteboard:aPasteboard];

	// Now set the cursor to the last char of the current paste.
	
	[self getSel:&start :&end];
	[self setSel:end.cp :end.cp];
	
	return self;
}

- (BOOL)hasEmptySelection
{
	NXSelPt	start;
	NXSelPt	end;

	[self getSel:&start :&end];
	
	if( start.cp == end.cp || 
	    start.cp < 0 )
		return YES;
	
	return NO;
}

- (BOOL)hasInvalidSelection
{
	NXSelPt	start;
	NXSelPt	end;

	[self getSel:&start :&end];
	
	if( start.cp < 0 ||
		end.cp < 0 )
		return YES;
	
	return NO;
}

- setSelToStart
{
	return [self setSel:0 :0];
}

- setSelToEnd
{
	return [self setSel:[self textLength] :[self textLength]];
}

- selectTrueLine:(int)line;
{
	int	start;
	int	stop;
	
	// To be
	
	if( line < 1 )
	{
		[self setSelToStart];
		return nil;
	}
	
	start = [self positionFromLine:line];
	stop = [self positionFromLine:line+1];
	
	if( stop < start )
		stop = [self textLength];
		
	[self setSel: start :stop];
	return self;
}

- findPerviousWord
{
	return self;
}

- findNextWord
{
	return self;
}

- (BOOL)findText:(const char *)string ignoreCase:(BOOL)ignoreCaseflag backwards:(BOOL)backwardsflag wrap:(BOOL)wrapflag font:aSharedFont
{
	BOOL		gotIt;
	NXSelPt	fromPos;
	NXSelPt	toPos;
	int		firstHit;

	firstHit = -2;
	gotIt = NO;

	while( !gotIt )
	{
		gotIt = [self findText:string ignoreCase:ignoreCaseflag
					 backwards:NO wrap:NO];
	
		// Now we should get the position of the found seleection.
		// we have to remember the first place where we have found something to
		// trace down inf-loops when we are allowed to do wraps!

		[self getSel:&fromPos :&toPos];

		if( !gotIt ||
			fromPos.cp == firstHit ) return NO;
		
		firstHit = fromPos.cp;

		// Now it seems like we have found the right string but
		// still this does not have to be the right font

		if( [self fontAtPosition:fromPos.cp] != aSharedFont ) gotIt = NO;
	}
	return YES;
}

- substringFromLine:(int)line
{
	int	from;
	int	length;

	from = [self positionFromLine:line];
	length = [self positionFromLine:line+1] - from;

	return [self getSubstringStringStart:from length:length];
}

// Working with Text runs and their information

- (NXRun *)textRunForPosition:(int)position
{
	BOOL 	found;
	int	i;
	int	currentOffset;
	
	currentOffset = 0;
	found = NO;

	for( i=0; i<theRuns->chunk.used; i++ )
	{
		if( currentOffset >= position )
		{
			found = YES;
			break;
		}
		currentOffset += theRuns->runs[i].chars;
	}

	return &(theRuns->runs[i]);
}

- fontsInsideSelection
{
	return self;
}

- fontAtPosition:(int)position
{
	NXRun *aRun;

	aRun = [self textRunForPosition:position];
	return aRun->font;
}

@end

/*
 * History: 30.01.95 Buh
 *			
 *
 * Bugs: - ...
 */